<?php
/**
 * Created by PhpStorm.
 * User: Kau
 * Date: 2017/12/31
 * Time: 20:44
 */
namespace app\models;

use yii\db\ActiveRecord;
use yii\helpers\ArrayHelper;

class Category extends ActiveRecord {
    public static function tableName()
    {
        return '{{%category}}';
    }

    public function attributeLabels()
    {
        return [
            'parentid' => '上级分类',
            'title' => '分类名称'
            ];
    }

    public function rules()
    {
        return [
            ['parentid', 'required', 'message' => '上级分类不能为空'],
            ['title', 'required', 'message' => '分类名称不能为空'],
            ['createtime', 'safe']
        ];
    }

    /**
     * 添加新分类
     * @param $data
     * @return bool
     */
    public function add($data) {
        $data['Category']['createtime'] = time();
        if ($this->load($data) && $this->save()) {
            return true;
        }
        return false;
    }

    /**
     * 获取数据库中的所有分类信息
     * @return Category[]|array|ActiveRecord[]
     */
    public function getData() {
        $cates = self::find()->all();
        $cates = ArrayHelper::toArray($cates);
        return $cates;
    }

    /**
     * 将分类信息传入并排好序，顶级分类与其次级分类
     * @param $cates
     * @param int $pid
     * @return array
     */
    public function getTree($cates, $pid = 0) {
        $tree = [];
        foreach ($cates as $cate) {
            if ($cate['parentid'] == $pid) {        // 循环遍历所有分类信息如果父级为$pid则加入数组中
                $tree[] = $cate;
                // 合并数组，且递归调用，将其子分录目录排序出来
                $tree = array_merge($tree ,$this->getTree($cates, $cate['cateid']));
            }
        }
        return $tree;
    }

    /**
     * 将排序好的分类目录传入并添加相应的前缀
     * @param $data
     * @param string $p
     * @return array
     */
    public function setPrefix($data, $p = "|---") {
        $tree = [];
        $num = 1;
        $prefix = [0 => 1]; // 顶级目录为一个前缀，二级目录为两个......

        while ($val = current($data)) {
            $key = key($data);
            if ($key > 0) {
                if ($data[$key - 1]['parentid'] != $val['parentid']) { // 如果上一次循环的parentid不等于当前循环的parentid
                    $num++; // 则本级目录为上次分类目录的子级目录（否则为同级目录），所以前缀数目++
                }
            }
            if (array_key_exists($val['parentid'], $prefix)) {  // 如果当前循环的parentid值已在$prefix中记录在案
                $num = $prefix[$val['parentid']];   // 前缀数目取$prefix中已存储的数据
            } // 若不检测其是否存在并取出使用，则程序默认会将非同级目录前缀数目无限+1
            $val['title'] = str_repeat($p, $num).$val['title'];
            $prefix[$val['parentid']] = $num;   // 将当前目录等级的前缀数目记录下来
            $tree[] = $val;
            next($data);
        }

        return $tree;
    }

    /**
     * 返回给前端添加分类目录
     * @return array
     */
    public function getOptions() {
        $data = $this->getData();
        $tree = $this->getTree($data);
        $tree = $this->setPrefix($tree);
        $options = ['添加顶级分类'];
        foreach ($tree as $cate) {
            $options[$cate['cateid']] = $cate['title'];
        }
        return $options;
    }

    public function getTreeList() {
        $data = $this->getData();
        $tree = $this->getTree($data);
        return $tree = $this->setPrefix($tree);
    }

}